package com.ethan.erouter_compiler;

import com.ethan.erouter_base.ERouterAction;
import com.google.auto.service.AutoService;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeSpec;

import java.io.IOException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Filer;
import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;

import static javax.lang.model.element.Modifier.*;

@AutoService(Processor.class)
public class ERouterCompiler extends AbstractProcessor {

    private Messager mMessager;
    private Elements mElementUtils;
    private Filer mFiler;

    @Override
    public Set<String> getSupportedAnnotationTypes() {
        Set<String> supportSet = new HashSet<>();
        supportSet.add(ERouterAction.class.getCanonicalName());

        return supportSet;
    }

    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.RELEASE_8;
    }

    @Override
    public synchronized void init(ProcessingEnvironment processingEnvironment) {
        super.init(processingEnvironment);
        mMessager = processingEnv.getMessager();
        mFiler = processingEnvironment.getFiler();
        mElementUtils = processingEnv.getElementUtils();
    }

    @Override
    public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
        Map<String, String> modelNameMap = processingEnv.getOptions();
        String modelNameStr = "";
        if (modelNameMap != null && !modelNameMap.isEmpty()) {
            modelNameStr = modelNameMap.get("moduleName");
        }

        MethodSpec.Builder loadPathBuilder = MethodSpec.methodBuilder("loadPath")
                .addAnnotation(Override.class)
                .addModifiers(Modifier.PUBLIC)
                .addParameter(Map.class, "map")
                .returns(void.class);

        Set<? extends Element> elements = roundEnvironment.getElementsAnnotatedWith(ERouterAction.class);
        for (Element e : elements) {
            ERouterAction eRouterAction = e.getAnnotation(ERouterAction.class);
            System.out.println("--------" + e.getAnnotation(ERouterAction.class));
            String classNameStr = e.asType().toString();
            System.out.println("---------" + classNameStr);
            loadPathBuilder.addStatement("map.put($S,$S)", eRouterAction.path(), classNameStr);

        }
        TypeSpec typeSpec = TypeSpec.classBuilder(modelNameStr + "$Router")
                .addModifiers(Modifier.PUBLIC)
                .addSuperinterface(ClassName.get("com.ethan.erouter_core", "IERouter"))
                .addMethod(loadPathBuilder.build())
                .build();


        try {
            JavaFile.builder("com.ethan.router", typeSpec)
                    .addFileComment("ERouter 自动生成")
                    .build().writeTo(mFiler);
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("翻车了！");
        }
        return false;
    }
}
